package cc.sunni.activiti.controller;

import cc.sunni.activiti.pojo.UserInfoBean;
import cc.sunni.activiti.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jl
 * @since 2021/1/29 21:04
 */
@Api(tags = "历史任务管理")
@RestController
@RequestMapping("/history")
public class HistoryController {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;

    @GetMapping(value = "/list")
    @ApiOperation("查询我(当前登录用户)的历史任务")
    public R InstancesByUser(@AuthenticationPrincipal UserInfoBean userInfoBean) {
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .orderByHistoricTaskInstanceEndTime().asc()
                .taskAssignee(userInfoBean.getUsername())
                .list();
        return R.ok(historicTaskInstances);
    }

    @GetMapping(value = "/getInstancesByProcessInstanceId")
    @ApiOperation(value = "根据流程实例ID查询历史任务", tags = "查看整个流程的全部任务")
    @ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R getInstancesByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .orderByHistoricTaskInstanceEndTime().asc()
                .processInstanceId(processInstanceId)
                .list();
        return R.ok(historicTaskInstances);
    }

    @GetMapping("/highLineHistory")
    @ApiOperation("高亮显示流程历史")
    @ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R highLineHistory(@RequestParam("processInstanceId") String processInstanceId, @AuthenticationPrincipal UserInfoBean userInfoBean) {
        // 查询历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        // 读取BPMN
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        Process process = bpmnModel.getProcesses().get(0);
        // 获取所有流程FlowElement的信息
        Collection<FlowElement> flowElements = process.getFlowElements();
        Map<String, String> map = new HashMap<>();
        for (FlowElement flowElement : flowElements) {
            // 判断是否是线条
            if (flowElement instanceof SequenceFlow) {
                SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                String sourceRef = sequenceFlow.getSourceRef();
                String targetRef = sequenceFlow.getTargetRef();
                // 流程所有的连线节点 value是连线ID
                map.put(sourceRef + targetRef, sequenceFlow.getId());
            }
        }

        // 获取已经执行过的历史流程节点
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
        Set<String> keySet = new HashSet<>();
        for (HistoricActivityInstance h1 : list) {
            for (HistoricActivityInstance h2 : list) {
                if (h1 != h2) {
                    // 已经执行过的节点的连线组合
                    keySet.add(h1.getActivityId() + h2.getActivityId());
                }
            }
        }

        // 高亮连线ID
        Set<String> highLine = keySet.stream().map(map::get).collect(Collectors.toSet());
        // 已完成的节点
        Set<String> highPoint = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).finished().list().stream().map(HistoricActivityInstance::getActivityId).collect(Collectors.toSet());
        // 当前待办节点
        Set<String> waitTodo = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).unfinished().list().stream().map(HistoricActivityInstance::getActivityId).collect(Collectors.toSet());

        // 当前用户已完成的任务
        List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userInfoBean.getUsername())
                .finished()
                .processInstanceId(processInstanceId).list();
        Set<String> iDo = taskInstanceList.stream().map(HistoricTaskInstance::getTaskDefinitionKey).collect(Collectors.toSet());

        Map<String, Object> result = new HashMap<>();
        result.put("highPoint", highPoint);
        result.put("highLine", highLine);
        result.put("waitingToDo", waitTodo);
        result.put("iDo", iDo);

        return R.ok(result);
    }
}
